/*
 * To characterange this template, characteroose Tools | Templates
 * and open the template in the editor.
 */
package packer;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 *
 * @author Bartek
 */
public class UnpackerInputStream extends FilterInputStream {
    
    public UnpackerInputStream(InputStream in) {
        super(in);
    }
    
    @Override
    public int read(byte[] bytes, int off, int len) throws IOException {
        
        byte[] compressedBytes = new byte[(int)(3.0 * Math.ceil(len / 4.0))];
        
        int numberOfBytesRead = super.in.read(compressedBytes, off, compressedBytes.length);
        
        if (numberOfBytesRead != -1) {

            StringBuilder compressedBinaryStringBuilder = new StringBuilder();

            for (int i = 0; i < numberOfBytesRead; i++) {
                String binaryString = String.format("%8s", 
                        Integer.toBinaryString(compressedBytes[i] & 0xFF)).replace(' ', '0');

                compressedBinaryStringBuilder.append(binaryString);
            }

            String compressedBinaryString = compressedBinaryStringBuilder.toString();

            //byte[] decompressedBytes = new byte[4 * bytes.length / 3];

            for (int i = 0; i < compressedBinaryString.length(); i += 6) {
                bytes[i/6] = (byte)getCharacterFromCode(Byte.parseByte(compressedBinaryString
                        .substring(i, i + 6), 2));
            }

            //System.arraycopy(dec, srcPos, bytes, destPos, length);
            return bytes.length;
        }
        else {
            return -1;
        }
    }
    
    private char getCharacterFromCode(byte code) {
        char character;
        
	switch(code){
		case 0:character=' ';break; case 1:character='a';break;
		case 2:character='b';break; case 3 :character='c';break;
		case 4:character='d';break; case 5 :character='e';break;
		case 6:character='f';break; case 7 :character='g';break;
		case 8:character='h';break; case 9 :character='i';break;
		case 10:character='j';break; case 11:character='k';break;
		case 12:character='l';break; case 13:character='m';break;
		case 14:character='n';break; case 15:character='o';break;
		case 16:character='p';break; case 17:character='q';break;
		case 18:character='r';break; case 19:character='s';break;
		case 20:character='t';break; case 21:character='u';break;
		case 22:character='v';break; case 23:character='w';break;
		case 24:character='x';break; case 25:character='y';break;
		case 26:character='z';break; case 27:character='.';break;
		case 28:character='*';break; case 29:character=',';break;
		case 30:character='\\';break; case 31 :character='2';break;
		case 32:character='A';break; case 33:character='B';break;
		case 34:character='C';break; case 35:character='D';break;
		case 36:character='E';break; case 37:character='F';break;
		case 38:character='G';break; case 39:character='H';break;
		case 40:character='I';break; case 41:character='J';break;
		case 42:character='K';break; case 43:character='L';break;
		case 44:character='M';break; case 45:character='N';break;
		case 46:character='O';break; case 47:character='P';break;
		case 48:character='Q';break; case 49:character='R';break;
		case 50:character='S';break; case 51:character='T';break;
		case 52:character='U';break; case 53:character='V';break;
		case 54:character='W';break; case 55:character='0';break;
		case 56:character='1';break; case 57:character='3';break;
		case 58:character='4';break; case 59:character='5';break;
		case 60:character='6';break; case 61:character='7';break;
		case 62:character='8';break; case 63:character='9';break;
		default:character=' ';
	}
	return character;
    }
}
